#include <iostream>
#include <map>
#include <string>

 
class Shape;
class Circle;
class Triangle;

typedef Shape *(*FactoryFunction)();


 
class Shape
{
public:
    virtual void  Draw()  = 0;
};

class Circle : public Shape
{
public:
    void Draw()  { 
		std::cout << "Drawing a Circle......Done" << std::endl; 
	}

    static Shape *createInstance() {
		return new Circle;
	}

};

 
class Triangle : public Shape

{
public:
	void Draw()  { 
		std::cout << "Drawing a Triagnle " << i << "      ....Done" << std::endl; 
	}

    static Shape *createInstance() {
		std::cout << "Triagnle createInstance" << std::endl; 
		return new Triangle;
	}
private:
	Triangle() { i++;}
	static int i;
};

int Triangle::i = 0;

class ShapeFactory
{
public:
    static void Register(std::string name, FactoryFunction instanceFunction) {
		std::cout << m_FactoryFunctions.size() << std::endl;
		m_FactoryFunctions[name] = instanceFunction;
	};

    static Shape * getInstance(std::string name) { 
		std::cout << m_FactoryFunctions.size() << std::endl;
		std::cout << "this is ShapeFactory::getInstance" << std::endl;
		if (m_FactoryFunctions.count(name))  
			return m_FactoryFunctions[name]();
		else
			return NULL; 
	}
private:
	ShapeFactory() {
		std::cout << "ShapeFactory::initializer" << std::endl;
		ShapeFactory::Register("circle",   &Circle::createInstance);
        ShapeFactory::Register("Triangle", &Triangle::createInstance);
	}
    static std::map<std::string,FactoryFunction> m_FactoryFunctions;
	static char * ff;
};

char * ShapeFactory::ff = "fffffffffffffffff"; 

std::map<std::string,FactoryFunction> ShapeFactory::m_FactoryFunctions; 

int main()
{
       ShapeFactory::Register("circle",   &Circle::createInstance);
       ShapeFactory::Register("Triangle", &Triangle::createInstance);
       ShapeFactory::Register("Triangle", &Triangle::createInstance);
       ShapeFactory::Register("Triangle", &Triangle::createInstance);
       ShapeFactory::Register("Triangle", &Triangle::createInstance);

       Shape * pShape = NULL;

       pShape = ShapeFactory::getInstance("Triangle");
       Shape * pShape1 = ShapeFactory::getInstance("Triangle");
       Shape * pShape2 = ShapeFactory::getInstance("Triangle");
	   std::cout << pShape << pShape1 << pShape2 << std::endl;

       if (NULL == pShape)
       {
              std::cout << "can't find the product in the factory" << std::endl;
              delete pShape;
       }
       else
       {
              pShape->Draw();
              delete pShape;
       }
       return 0;
}

